package pt.ipleiria.plp;

import pt.ipleiria.plp.Lixeiras.Lixeira;
import pt.ipleiria.plp.Lixeiras.LixeiraChangedState;
import pt.ipleiria.plp.Lixeiras.LixeiraEdited;
import pt.ipleiria.plp.Lixeiras.LixeiraSendResult;
import pt.ipleiria.plp.Lixeiras.LixeiraNew;
import pt.ipleiria.plp.Lixeiras.LixeiraSent;
import java.io.IOException;
import javax.microedition.location.Coordinates;
import javax.microedition.location.LocationException;
import pt.ipleiria.plp.stub.BlackSpotState;
import pt.ipleiria.plp.stub.WasteVolume;

/**
 * Class desveloped to test the system requirements without a gui
 * @author Filipe Felisberto e Ricardo Silva
 */
public class TestLogic {

    public static final String APP_KEY2 = "RB-app2Key";
    public static final String APP_KEY1 = "RB-app1Key";
    private String guid = "12345678-1234-1234-1234-123456789012";
    private float lat = 40;
    private float longe = -8;
    private String testAPP;
    private String guid_test;

    public TestLogic(String app) {
        testAPP = app;
    }

    /**
     * Function to instaciate a test Lixeira
     * @return the lixeira
     */
    private LixeiraNew testCreateLixeira() {

        LixeiraNew newLix = new LixeiraNew(guid, "test", lat,
                longe, WasteVolume.Small, new String[]{Lixeira.GLASS, Lixeira.AUTOMOTIVE},
                11, "20kg", "Apenas um teste", new String[]{"tag1", "tag2"},
                BlackSpotState.Resolved);

        System.out.print("Test Create Lixeira  --> ");
        if (newLix != null) {
            System.out.println("Sucsessful");
        } else {
            System.out.println("Failed");
        }
        return newLix;
    }

    /**
     * Tests the edit of a Lixeira
     * @param lix the lixeira to be edited
     * @return the sent lixeira
     */
    private LixeiraSent testEditLixeira(LixeiraSent lix) {

        System.out.print("Test Edit Lixeira with id: " + lix.getGuid() + " --> ");
        try {
            LixeiraEdited edit = new LixeiraEdited(lix, lix.getBs().getLatitude(),
                    lix.getBs().getLongitude(), lix.getBs().getQuantity(),
                    lix.getBs().getClassification(),
                    lix.getBs().getEstimatedNumberVolunteers(),
                    lix.getBs().getEstimatedWasteVolume(), "ALTERADO",
                    lix.getBs().getTags().getString(),false);

            LixeiraSendResult sent = edit.send(testAPP);
            if (sent.wasSuceded()) {
                System.out.println("Sucsessful");
            } else {
                System.out.println("Failed");
                System.out.println("Error: " + sent.getError());
            }

            return sent.getLixeira();


        } catch (IllegalArgumentException ex) {
            System.out.println("Failed");
            System.out.println("Error: " + ex.getMessage());

        } catch (Exception ex) {
            System.out.println("Failed");
            System.out.println("Error: " + ex.getMessage());
        }

        return null;

    }

    /**
     * Tests the sending of a lixeira
     * @param lix the lixeira to be sent
     * @return the lixiera that was sent
     */
    private LixeiraSent testSendLixeira(LixeiraNew lix) {

        LixeiraSendResult sent = lix.send(testAPP);

        System.out.print("Test Send Lixeira  --> ");
        if (sent == null) {

            System.out.println("Failed");
            return null;
        }
        if (sent.wasSuceded()) {
            guid_test = sent.getNewGuid();
            System.out.println("Guid-" + guid_test);
            System.out.println("Sucsessful");
        } else {
            System.out.println("Failed");
            System.out.println("Error: " + sent.getError());
        }
        return sent.getLixeira();

    }

    /**
     * Test the direct change state
     * @param lix the lixeira to change state
     * @return the changed lixeira
     */
    private LixeiraSent testChangeState(LixeiraSent lix) {

        LixeiraChangedState lixC = lix.changeState(BlackSpotState.Unconfirmed, testAPP);
        System.out.print("Test Change State Lixeira  --> ");
        if (lixC == null) {
            System.out.println("Sucsessful");

        } else {
            System.out.println("Failed");
        }

        return lix;
    }

    /**
     * Tests is the fuction that retrieves the data from the server is working
     * @param lix the lixeira to get
     * @return true if Sucsessful
     */
    private boolean testGetLixeiraFromServer(LixeiraSent lix) {
        //to be sure that the BS field is really null;
        LixeiraSent lixToRet = new LixeiraSent(lix.getGuid(), lix.getTitle(),
                lix.getState());
        String error = lixToRet.getDataFromServer(testAPP);

        System.out.print("Test Retrieve Lixeira  --> ");
        if (error == null) {
            System.out.println("Sucsessful");
            System.out.println("ID: " + lixToRet.getBs().getSpotId());
            System.out.println("Notes: " + lixToRet.getBs().getNotes());

            return true;
        } else {
            System.out.println("Failed");
            System.err.println("Error: " + error);
            return false;
        }


    }

    /**
     * Tests the save to and load from the phone memmory
     * @return true if Sucsessful
     */
    private boolean testPersistLixeira(LixeiraSent sent) {
        System.out.print("Test Save Lixeira  --> ");

        LixeirasManager lixMan = new LixeirasManager(testAPP);

        lixMan.addLixeiraEnviada(sent);

        try {
            lixMan.save();
            System.out.println("Sucsessful");

        } catch (IOException ex) {

            System.out.println("Failed");
            System.err.println("Error: " + ex.getMessage());
            return false;

        }

        lixMan = new LixeirasManager(testAPP);

        System.out.print("Test Load Lixeira  --> ");
        if (lixMan.getLixeirasEnviadas().hasMoreElements()) {
            System.out.println("Sucsessful");
            return true;

        } else {
            System.out.println("Failed");
            return false;
        }

    }

    /**
     * Tests the deletion of the created Lixeira
     * @param lix to be deleted
     * @return true true if Sucsessful
     */
    private boolean testDeleteLixeira(LixeiraSent lix) {
        String error = lix.delete(testAPP);

        System.out.print("Test Delete Lixeira  --> ");
        if (error == null) {
            System.out.println("Sucsessful");
            return true;
        } else {
            System.out.println("Failed");
            System.err.println("Error: " + error);
            return false;
        }

    }

    /**
     * Test if the program can get GPS location
     * @return true true if Sucsessful
     */
    private boolean testGPS() {
        System.out.print("Test get GPS position  --> ");
        try {
            GPS gps = new GPS();

            Coordinates c;
            c = gps.getLocation();


            if (c != null) {
                System.out.println("Sucsessful");
                System.out.println("Lat: "+c.getLatitude()+" Longe: "+c.getLongitude());
                return true;
            } else {
                System.out.println("Failed");
                return false;
            }
        } catch (LocationException ex) {
            System.out.println("Failed");
            System.err.println("Error: "+ex.getMessage());
            return false;
        } catch (InterruptedException ex) {
            System.err.println("Error: "+ex.getMessage());
            return false;
        }
    }

    /**
     * executes all the tests
     */
    public void run() {

//        LixeiraNew lix = testCreateLixeira();
//        if (lix == null) {
//            return;
//        }
//
//        LixeiraSent lixS = testSendLixeira(lix);
//        if (lixS == null) {
//            return;
//        }

//        testPersistLixeira(lixS);
//
//        testGetLixeiraFromServer(lixS);
//
//        testChangeState(lixS);
//
//        testEditLixeira(lixS);
//
//        testDeleteLixeira(lixS);
        testGPS();

    }
}




